#include "LocalScene.h"
#include "Utils/LogUtil.h"
#include "LocalEntity.h"
#include "Utils/StringUtil.h"
#include "Game/Component/Model.h"
#include "Render/RenderState.h"
#include "Render/Imgui/imgui.h"
#include "Math/Random.h"
#include "Game/GameState.h"
#include "Shadows/ShadowsRayTraceProcess.h"
#include "Shadows/ShadowsTemporalAccumulationProcess.h"
#include "Shadows/ShadowsAtrousFilterProcess.h"
#include "AO/AORayTraceProcess.h"
#include "AO/AoDenoiseBilateralBlurProcess.h"
#include "AO/AoTemporalAccumulationProcess.h"
#include "DDGI/DdgiRayTraceProcess.h"
#include "DDGI/DdgiSampleProbeGridProcess.h"
#include "PreViewProcess.h"


#define INSIDE_ROOM 0

void LocalScene::OnInit()
{
	mCamera.SetSpeed(6.f);

	mCoordinateProcess = GetProcess<CoordinateProcess>("CoordinateProcess");

	mResourceProcess = GetProcess<ResourceProcess>("ResourceProcess");

	mShadowsRayTraceProcess = GetProcess<ShadowsRayTraceProcess>("ShadowsRayTraceProcess");

	mShadowsTemporalAccumulationProcess = GetProcess<ShadowsTemporalAccumulationProcess>("ShadowsTemporalAccumulationProcess");

	mShadowsAtrousFilterProcess = GetProcess<ShadowsAtrousFilterProcess>("ShadowsAtrousFilterProcess");

	mAoRayTraceProcess = GetProcess<AoRayTraceProcess>("AoRayTraceProcess");

	mAoDenoiseBilateralBlurProcess = GetProcess<AoDenoiseBilateralBlurProcess>("AoDenoiseBilateralBlurProcess");

	mAoTemporalAccumulationProcess = GetProcess<AoTemporalAccumulationProcess>("AoTemporalAccumulationProcess");

	mDdgiRayTraceProcess = GetProcess<DdgiRayTraceProcess>("DdgiRayTraceProcess");

	mDdgiSampleProbeGridProcess = GetProcess<DdgiSampleProbeGridProcess>("DdgiSampleProbeGridProcess");

	mPreViewProcess = GetProcess<PreViewProcess>("PreViewProcess");

	GeometryGenerator geometryGenerator;

#if INSIDE_ROOM

	GeometryGenerator::MeshData lightData = geometryGenerator.CreateSphere(0.3f, 20, 20);

	LocalEntity* lightEntity = CreateEntity<LocalEntity>("light");
	lightEntity->AddComponent<Model>(lightData);
	lightEntity->AddComponent<OpaqueObject>();
	lightEntity->GetTransform().SetLocalPosition(glm::vec3(0.f, 3.7f, 0.f));
	lightEntity->GetTransform().UpdateMatrices();

	lightEntity->mMaterial.albedo = glm::vec4(0.f, 0.75f, 0.1f, 1.f);


	GeometryGenerator::MeshData leftPanelData = geometryGenerator.CreatePanel(4.f, 6.f, glm::vec3(-1.f, 0.f, 0.f));

	LocalEntity* leftPanelEntity = CreateEntity<LocalEntity>("leftPanel");
	leftPanelEntity->AddComponent<Model>(leftPanelData);
	leftPanelEntity->AddComponent<OpaqueObject>();
	leftPanelEntity->GetTransform().SetLocalPosition(glm::vec3(4.f, 2.f, 0.f));
	leftPanelEntity->GetTransform().UpdateMatrices();

	leftPanelEntity->mMaterial.albedo = glm::vec4(0.65f, 0.05f, 0.05f, 1.f);


	GeometryGenerator::MeshData rightPanelData = geometryGenerator.CreatePanel(4.f, 6.f, glm::vec3(1.f, 0.f, 0.f));

	LocalEntity* rightPanelEntity = CreateEntity<LocalEntity>("rightPanel");
	rightPanelEntity->AddComponent<Model>(rightPanelData);
	rightPanelEntity->AddComponent<OpaqueObject>();
	rightPanelEntity->GetTransform().SetLocalPosition(glm::vec3(-4.f, 2.f, 0.f));
	rightPanelEntity->GetTransform().UpdateMatrices();

	rightPanelEntity->mMaterial.albedo = glm::vec4(0.12f, 0.45f, 0.15f, 1.f);


	GeometryGenerator::MeshData topPanelData = geometryGenerator.CreatePanel(8.f, 6.f, glm::vec3(0.f, -1.f, 0.f));

	LocalEntity* topPanelEntity = CreateEntity<LocalEntity>("topPanel");
	topPanelEntity->AddComponent<Model>(topPanelData);
	topPanelEntity->AddComponent<OpaqueObject>();
	topPanelEntity->GetTransform().SetLocalPosition(glm::vec3(0.f, 4.f, 0.f));
	topPanelEntity->GetTransform().UpdateMatrices();

	topPanelEntity->mMaterial.albedo = glm::vec4(0.72f, 0.84f, 0.96f, 1.f);


	GeometryGenerator::MeshData backPanelData = geometryGenerator.CreatePanel(8.f, 4.f, glm::vec3(0.f, 0.f, 1.f));

	LocalEntity* backPanelEntity = CreateEntity<LocalEntity>("backPanel");
	backPanelEntity->AddComponent<Model>(backPanelData);
	backPanelEntity->AddComponent<OpaqueObject>();
	backPanelEntity->GetTransform().SetLocalPosition(glm::vec3(0.f, 2.f, -3.f));
	backPanelEntity->GetTransform().UpdateMatrices();

	backPanelEntity->mMaterial.albedo = glm::vec4(0.85f, 0.85f, 0.f, 1.f);

	GeometryGenerator::MeshData bottomPanelData = geometryGenerator.CreatePanel(8.f, 6.f, glm::vec3(0.f, 1.f, 0.f));

#else

	GeometryGenerator::MeshData bottomPanelData = geometryGenerator.CreatePanel(32.f, 24.f, glm::vec3(0.f, 1.f, 0.f));

#endif

	LocalEntity* bottomPanelEntity = CreateEntity<LocalEntity>("bottomPanel");
	bottomPanelEntity->AddComponent<Model>(bottomPanelData);
	bottomPanelEntity->AddComponent<OpaqueObject>();
	bottomPanelEntity->GetTransform().SetLocalPosition(glm::vec3(0.f, 0.f, 0.f));
	bottomPanelEntity->GetTransform().UpdateMatrices();

	bottomPanelEntity->mMaterial.albedo = glm::vec4(0.90f, 0.72f, 0.88f, 1.f);


	LocalEntity* CoffeeTableEntity = CreateEntity<LocalEntity>("CoffeeTable");
	CoffeeTableEntity->AddComponent<Model>("CoffeeTable.obj");
	CoffeeTableEntity->AddComponent<OpaqueObject>();
	CoffeeTableEntity->GetTransform().SetLocalPosition(glm::vec3(0.f, 0.f, 1.6f));
	CoffeeTableEntity->GetTransform().SetLocalScale(glm::vec3(0.5f));
	CoffeeTableEntity->GetTransform().UpdateMatrices();

	CoffeeTableEntity->mMaterial.albedo = glm::vec4(1.0f, 0.765557f, 0.f, 1.f);


	LocalEntity* LampEntity = CreateEntity<LocalEntity>("Lamp");
	LampEntity->AddComponent<Model>("Lamp.obj");
	LampEntity->AddComponent<OpaqueObject>();
	LampEntity->GetTransform().SetLocalPosition(glm::vec3(2.f, 0.f, -1.6f));
	LampEntity->GetTransform().SetLocalScale(glm::vec3(0.5f));
	LampEntity->GetTransform().UpdateMatrices();

	LampEntity->mMaterial.albedo = glm::vec4(1.0f, 0.f, 0.f, 1.f);


	LocalEntity* CouchEntity = CreateEntity<LocalEntity>("Couch");
	CouchEntity->AddComponent<Model>("Couch.obj");
	CouchEntity->AddComponent<OpaqueObject>();
	CouchEntity->GetTransform().SetLocalPosition(glm::vec3(0.f, 0.f, -1.8f));
	CouchEntity->GetTransform().SetLocalScale(glm::vec3(0.5f));
	CouchEntity->GetTransform().UpdateMatrices();

	CouchEntity->mMaterial.albedo = glm::vec4(0.f, 0.765557f, 0.336057f, 1.f);


	LocalEntity* TeapotEntity = CreateEntity<LocalEntity>("Teapot");
	TeapotEntity->AddComponent<Model>("Teapot.obj");
	TeapotEntity->AddComponent<OpaqueObject>();
	TeapotEntity->GetTransform().SetLocalPosition(glm::vec3(0.2f, 0.84f, 0.2f));
	TeapotEntity->GetTransform().SetLocalScale(glm::vec3(0.1f));
	TeapotEntity->GetTransform().UpdateMatrices();

	TeapotEntity->mMaterial.albedo = glm::vec4(1.0f, 0.23f, 0.336057f, 1.f);


	LocalEntity* VenusEntity = CreateEntity<LocalEntity>("Venus");
	VenusEntity->AddComponent<Model>("Venus.obj");
	VenusEntity->AddComponent<OpaqueObject>();
	VenusEntity->GetTransform().SetLocalPosition(glm::vec3(-3.4f, 1.7f, 2.f));
	VenusEntity->GetTransform().SetLocalScale(glm::vec3(0.3f));
	VenusEntity->GetTransform().UpdateMatrices();

	VenusEntity->mMaterial.albedo = glm::vec4(1.0f, 0.8f, 0.f, 1.f);


	LocalEntity* SofaEntity = CreateEntity<LocalEntity>("Sofa");
	SofaEntity->AddComponent<Model>("Sofa.obj");
	SofaEntity->AddComponent<OpaqueObject>();
	SofaEntity->GetTransform().SetLocalPosition(glm::vec3(1.6f, -0.15f, -2.8f));
	SofaEntity->GetTransform().SetLocalScale(glm::vec3(1.4f));
	SofaEntity->GetTransform().UpdateMatrices();

	SofaEntity->mMaterial.albedo = glm::vec4(1.0f, 0.765557f, 0.336057f, 1.f);


	LocalEntity* AudioEntity = CreateEntity<LocalEntity>("Audio");
	AudioEntity->AddComponent<Model>("Audio.obj");
	AudioEntity->AddComponent<OpaqueObject>();
	AudioEntity->GetTransform().SetLocalPosition(glm::vec3(-2.8f, -1.f, -0.8f));
	AudioEntity->GetTransform().SetLocalScale(glm::vec3(2.f));
	AudioEntity->GetTransform().SetLocalOrientation(glm::quat(glm::vec3(0.f, glm::radians(-90.f), 0.f)));
	AudioEntity->GetTransform().UpdateMatrices();

	AudioEntity->mMaterial.albedo = glm::vec4(0.5f, 0.765557f, 0.336057f, 1.f);


	LocalEntity* Audio1Entity = CreateEntity<LocalEntity>("Audio1");
	Audio1Entity->AddComponent<Model>("Audio.obj");
	Audio1Entity->AddComponent<OpaqueObject>();
	Audio1Entity->GetTransform().SetLocalPosition(glm::vec3(-3.5f, -1.f, -0.8f));
	Audio1Entity->GetTransform().SetLocalScale(glm::vec3(2.f));
	Audio1Entity->GetTransform().SetLocalOrientation(glm::quat(glm::vec3(0.f, glm::radians(-90.f), 0.f)));
	Audio1Entity->GetTransform().UpdateMatrices();

	Audio1Entity->mMaterial.albedo = glm::vec4(0.5f, 0.765557f, 0.336057f, 1.f);


	LocalEntity* Audio2Entity = CreateEntity<LocalEntity>("Audio2");
	Audio2Entity->AddComponent<Model>("Audio.obj");
	Audio2Entity->AddComponent<OpaqueObject>();
	Audio2Entity->GetTransform().SetLocalPosition(glm::vec3(-4.2f, -1.f, -0.8f));
	Audio2Entity->GetTransform().SetLocalScale(glm::vec3(2.f));
	Audio2Entity->GetTransform().SetLocalOrientation(glm::quat(glm::vec3(0.f, glm::radians(-90.f), 0.f)));
	Audio2Entity->GetTransform().UpdateMatrices();

	Audio2Entity->mMaterial.albedo = glm::vec4(0.5f, 0.765557f, 0.336057f, 1.f);


	LocalEntity* TableEntity = CreateEntity<LocalEntity>("Table");
	TableEntity->AddComponent<Model>("Table.obj");
	TableEntity->AddComponent<OpaqueObject>();
	TableEntity->GetTransform().SetLocalPosition(glm::vec3(0.f, 0.f, 0.f));
	TableEntity->GetTransform().SetLocalScale(glm::vec3(0.02f, 0.02f, 0.011f));
	TableEntity->GetTransform().SetLocalOrientation(glm::quat(glm::vec3(0.f, glm::radians(90.f), glm::radians(90.f))));
	TableEntity->GetTransform().UpdateMatrices();

	TableEntity->mMaterial.albedo = glm::vec4(1.0f, 0.765557f, 0.336057f, 1.f);



	LocalEntity* TVEntity = CreateEntity<LocalEntity>("TV");
	TVEntity->AddComponent<Model>("TV.obj");
	TVEntity->AddComponent<OpaqueObject>();
	TVEntity->GetTransform().SetLocalOrientation(glm::quat(glm::vec3(0.f, glm::radians(-90.f), 0.f)));
	TVEntity->GetTransform().SetLocalPosition(glm::vec3(-2.6f, 0.f, 0.f));
	TVEntity->GetTransform().SetLocalScale(glm::vec3(2.f));
	TVEntity->GetTransform().UpdateMatrices();

	TVEntity->mMaterial.albedo = glm::vec4(1.0f, 0.765557f, 0.336057f, 1.f);


	GeometryGenerator::MeshData TVBoardData = geometryGenerator.CreatePanel(1.46f, 2.84f, glm::vec3(-1.f, 0.f, 0.f));

	LocalEntity* TVBoardEntity = CreateEntity<LocalEntity>("TVBoard");
	TVBoardEntity->AddComponent<Model>(TVBoardData);
	TVBoardEntity->AddComponent<OpaqueObject>();
	TVBoardEntity->GetTransform().SetLocalPosition(glm::vec3(3.91f, 2.63f, 0.02f));
	TVBoardEntity->GetTransform().UpdateMatrices();

	TVBoardEntity->mMaterial.albedo = glm::vec4(0.65f, 0.01f, 0.045f, 1.f);



	LocalEntity* LionHeadEntity = CreateEntity<LocalEntity>("LionHead");
	LionHeadEntity->AddComponent<Model>("LionHead.obj");
	LionHeadEntity->AddComponent<OpaqueObject>();
	LionHeadEntity->GetTransform().SetLocalPosition(glm::vec3(-2.f, 2.f, -3.f));
	LionHeadEntity->GetTransform().SetLocalScale(glm::vec3(0.06f));
	LionHeadEntity->GetTransform().SetLocalOrientation(glm::quat(glm::vec3(glm::radians(-90.f), 0.f, 0.f)));
	LionHeadEntity->GetTransform().UpdateMatrices();

	LionHeadEntity->mMaterial.albedo = glm::vec4(0.6f, 0.2f, 0.336057f, 1.f);


	LocalEntity* DogHeadEntity = CreateEntity<LocalEntity>("DogHead");
	DogHeadEntity->AddComponent<Model>("DogHead.obj");
	DogHeadEntity->AddComponent<OpaqueObject>();
	DogHeadEntity->GetTransform().SetLocalPosition(glm::vec3(1.2f, 2.f, -3.f));
	DogHeadEntity->GetTransform().SetLocalScale(glm::vec3(0.06f));
	DogHeadEntity->GetTransform().SetLocalOrientation(glm::quat(glm::vec3(glm::radians(-90.f), 0.f, 0.f)));
	DogHeadEntity->GetTransform().UpdateMatrices();

	DogHeadEntity->mMaterial.albedo = glm::vec4(0.6f, 0.2f, 0.336057f, 1.f);


	LocalEntity* FoxHeadEntity = CreateEntity<LocalEntity>("FoxHead");
	FoxHeadEntity->AddComponent<Model>("FoxHead.obj");
	FoxHeadEntity->AddComponent<OpaqueObject>();
	FoxHeadEntity->GetTransform().SetLocalPosition(glm::vec3(-0.4f, 2.f, -3.f));
	FoxHeadEntity->GetTransform().SetLocalScale(glm::vec3(0.06f));
	FoxHeadEntity->GetTransform().SetLocalOrientation(glm::quat(glm::vec3(glm::radians(-90.f), 0.f, 0.f)));
	FoxHeadEntity->GetTransform().UpdateMatrices();

	FoxHeadEntity->mMaterial.albedo = glm::vec4(0.6f, 0.2f, 0.336057f, 1.f);

#if 0
	LocalEntity* GrooveEntity = CreateEntity<LocalEntity>("Groove");
	GrooveEntity->AddComponent<Model>("Groove.obj");
	GrooveEntity->AddComponent<OpaqueObject>();
	GrooveEntity->GetTransform().SetLocalOrientation(glm::quat(glm::vec3(0.f, glm::radians(90.f), 0.f)));
	GrooveEntity->GetTransform().SetLocalPosition(glm::vec3(4.1f, 2.5f, 0.f));
	GrooveEntity->GetTransform().SetLocalScale(glm::vec3(2.f));
	GrooveEntity->GetTransform().UpdateMatrices();

	GrooveEntity->mMaterial.albedo = glm::vec4(0.4f, 0.f, 0.336057f, 1.f);


	LocalEntity* CurtainEntity = CreateEntity<LocalEntity>("Curtain");
	CurtainEntity->AddComponent<Model>("Curtain.obj");
	CurtainEntity->AddComponent<OpaqueObject>();
	CurtainEntity->GetTransform().SetLocalPosition(glm::vec3(5.6f, 1.6f, -2.8f));
	CurtainEntity->GetTransform().SetLocalScale(glm::vec3(1.f));
	CurtainEntity->GetTransform().UpdateMatrices();

	CurtainEntity->mMaterial.albedo = glm::vec4(0.2f, 0.f, 0.936057f, 1.f);
#endif


	LocalEntity* PianoEntity = CreateEntity<LocalEntity>("Piano");
	PianoEntity->AddComponent<Model>("Piano.obj");
	PianoEntity->AddComponent<OpaqueObject>();
	PianoEntity->GetTransform().SetLocalPosition(glm::vec3(1.f, 0.f, 3.4f));
	PianoEntity->GetTransform().SetLocalScale(glm::vec3(2.f));
	PianoEntity->GetTransform().UpdateMatrices();

	PianoEntity->mMaterial.albedo = glm::vec4(1.0f, 0.765557f, 0.336057f, 1.f);






#if 0
	LocalEntity* CoffeeTableEntity = CreateEntity<LocalEntity>("CoffeeTable");
	CoffeeTableEntity->AddComponent<Model>("CoffeeTable.obj");
	CoffeeTableEntity->GetTransform().SetLocalPosition(glm::vec3());
	CoffeeTableEntity->GetTransform().SetLocalScale(glm::vec3(0.3f));
	CoffeeTableEntity->GetTransform().UpdateMatrices();

	CoffeeTableEntity->mMaterial.albedo = glm::vec4(1.0f, 0.765557f, 0.336057f, 1.f);
#endif

	mGBufferIndex = 0;

	mLightTypeNames = { "Directional", "Point", "Spot" };

	mLightTransformOperation = ImGuizmo::ROTATE;
	mLightTransform = glm::mat4(1.0f);
	mLightRadius = 0.1f;
	mLightDirection = glm::normalize(glm::vec3(0.568f, 0.707f, -0.421f));
	mLightPosition = glm::vec3(5.0f);
	mLightColor = glm::vec3(1.0f);
	mLightIntensity = 1.0f;
	mLightConeAngleInner = 40.0f;
	mLightConeAngleOuter = 50.0f;
	mLightType = LIGHT_TYPE_DIRECTIONAL;

	ResetLight();
}

void LocalScene::OnTick(float deltaTime)
{
	mLightDirection = glm::normalize(glm::mat3(mLightTransform) * glm::vec3(0.0f, -1.0f, 0.0f));
	mLightPosition = glm::vec3(mLightTransform[3][0], mLightTransform[3][1], mLightTransform[3][2]);



}

void LocalScene::OnImgui()
{
	bool open = true;
	ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_HorizontalScrollbar;

	ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f));
	ImGui::SetNextWindowSize(ImVec2(GRenderState->GetWidth() * 0.2f, GRenderState->GetHeight() * 0.75f));

	if (ImGui::Begin("Hybrid Rendering", &open, window_flags))
	{
		ImGui::Text("Fps : %d ", GRenderState->GetFps());

		if (ImGui::TreeNode("Light"))
		{
			LightType type = mLightType;

			if (ImGui::BeginCombo("Type", mLightTypeNames[type].c_str()))
			{
				for (uint32_t i = 0; i < mLightTypeNames.size(); i++)
				{
					const bool isLightselected = (i == type);

					if (ImGui::Selectable(mLightTypeNames[i].c_str(), isLightselected))
						type = (LightType)i;

					if (isLightselected)
						ImGui::SetItemDefaultFocus();
				}
				ImGui::EndCombo();
			}

			if (mLightType != type)
			{
				mLightType = type;
				ResetLight();
			}

			if (mLightType == LIGHT_TYPE_DIRECTIONAL)
				DirectionalLightGui();
			else if (mLightType == LIGHT_TYPE_POINT)
				PointLightGui();
			else if (mLightType == LIGHT_TYPE_SPOT)
				SpotLightGui();

			ImGui::TreePop();
			ImGui::Separator();
		}

		if (ImGui::TreeNode("Shadows"))
		{
			ImGui::InputFloat("Bias", &mShadowsRayTraceProcess->mPushConstants.bias);
			ImGui::InputFloat("Alpha", &mShadowsTemporalAccumulationProcess->mPushConstants.alpha);
			ImGui::InputFloat("Alpha Moments", &mShadowsTemporalAccumulationProcess->mPushConstants.momentsAlpha);
			ImGui::InputFloat("Phi Visibility", &mShadowsAtrousFilterProcess->mPushConstants.phiVisibility);
			ImGui::InputFloat("Phi Normal", &mShadowsAtrousFilterProcess->mPushConstants.phiNormal);
			ImGui::InputFloat("Sigma Depth", &mShadowsAtrousFilterProcess->mPushConstants.sigmaDepth);
			ImGui::SliderInt("Filter Iterations", &mShadowsAtrousFilterProcess->mFilterIterations, 1, 5);
			ImGui::SliderFloat("Power", &mShadowsAtrousFilterProcess->mPushConstants.power, 1.0f, 50.0f);

			ImGui::TreePop();
			ImGui::Separator();
		}

		if (ImGui::TreeNode("AO"))
		{
			ImGui::SliderFloat("Ray Length", &mAoRayTraceProcess->mPushConstants.rayLength, 1.0f, 100.0f);
			ImGui::InputFloat("Bias", &mAoRayTraceProcess->mPushConstants.bias);
			ImGui::SliderFloat("Temporal Alpha", &mAoTemporalAccumulationProcess->mPushConstants.alpha, 0.0f, 0.5f);
			ImGui::SliderInt("Blur Radius", &mAoDenoiseBilateralBlurProcess->mPushConstants.radius, 1, 10);

			ImGui::TreePop();
			ImGui::Separator();
		}

		if (ImGui::TreeNode("DDGI"))
		{
			ImGui::Text("Grid Size: [%i, %i, %i]", mDdgiRayTraceProcess->mProbeCounts.x, mDdgiRayTraceProcess->mProbeCounts.y, mDdgiRayTraceProcess->mProbeCounts.z);
			ImGui::Text("Probe Count: %i", mDdgiRayTraceProcess->mProbeCounts.x * mDdgiRayTraceProcess->mProbeCounts.y * mDdgiRayTraceProcess->mProbeCounts.z);
			ImGui::Checkbox("Visibility Test", &mDdgiRayTraceProcess->mVisibilityTest);
			ImGui::Checkbox("Infinite Bounces", &mDdgiRayTraceProcess->mInfiniteBounces);

			/*if (ImGui::InputInt("Rays Per Probe", &m_ray_trace.rays_per_probe))
				recreate_probe_grid_resources();
			if (ImGui::InputFloat("Probe Distance", &m_probe_grid.probe_distance))
				initialize_probe_grid();*/

			ImGui::InputFloat("Hysteresis", &mDdgiRayTraceProcess->mHysteresis);
			ImGui::SliderFloat("Infinite Bounce Intensity", &mDdgiRayTraceProcess->mPushConstants.giIntensity, 0.0f, 10.0f);
			ImGui::SliderFloat("GI Intensity", &mDdgiSampleProbeGridProcess->mPushConstants.giIntensity, 0.0f, 10.0f);
			ImGui::SliderFloat("Normal Bias", &mDdgiRayTraceProcess->mNormalBias, 0.0f, 10.0f);
			ImGui::InputFloat("Depth Sharpness", &mDdgiRayTraceProcess->mDepthSharpness);

			ImGui::TreePop();
			ImGui::Separator();
		}

		if (ImGui::TreeNode("Cubemap"))
		{
			ImGui::InputFloat("Roughness", &mPreViewProcess->mPushConstants.roughness, 0.1f, 0.1f);

			ImGui::TreePop();
			ImGui::Separator();
		}

		ImGui::End();
	}

}

void LocalScene::ResetLight()
{
	mLightTransform = glm::mat4(1.0f);

	if (mLightType == LIGHT_TYPE_DIRECTIONAL)
	{
		mLightRadius = 0.1f;
		mLightIntensity = 1.0f;

		mLightTransform = glm::rotate(mLightTransform, glm::radians(50.0f), glm::vec3(0.0f, 1.0f, 0.0f)) * glm::rotate(glm::mat4(1.0f), glm::radians(50.0f), glm::vec3(1.0f, 0.0f, 0.0f));
	}
	else if (mLightType == LIGHT_TYPE_POINT)
	{
		mLightRadius = 2.5f;
		mLightIntensity = 500.0f;

		mLightTransform = glm::translate(glm::mat4(1.0f), glm::vec3(0.f, 2.f, 0.f));
	}
	else if (mLightType == LIGHT_TYPE_SPOT)
	{
		mLightRadius = 2.5f;
		mLightIntensity = 500.0f;
		mLightConeAngleInner = 40.0f;
		mLightConeAngleOuter = 50.0f;

		glm::mat4 R = glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f));
		glm::mat4 T = glm::translate(glm::mat4(1.0f), glm::vec3(0.f, 2.f, 0.f));

		mLightTransform = T * R;
	}
}

void LocalScene::DirectionalLightGui()
{
	mLightTransformOperation = ImGuizmo::OPERATION::ROTATE;

	ImGui::ColorEdit3("Color", &mLightColor.x);
	ImGui::InputFloat("Intensity", &mLightIntensity);
	ImGui::SliderFloat("Radius", &mLightRadius, 0.0f, 0.1f);

	glm::vec3 position;
	glm::vec3 rotation;
	glm::vec3 scale;

	ImGuizmo::BeginFrame();
	ImGuizmo::SetOrthographic(false);

	ImGuizmo::DecomposeMatrixToComponents(&mLightTransform[0][0], &position.x, &rotation.x, &scale.x);

	ImGui::InputFloat3("Rotation", &rotation.x);

	ImGuizmo::RecomposeMatrixFromComponents(&position.x, &rotation.x, &scale.x, &mLightTransform[0][0]);

	ImGuizmo::SetRect(0, 0, GRenderState->GetWidth(), GRenderState->GetHeight());
	ImGuizmo::Manipulate(&mCamera.mZmoView[0][0], &mCamera.mProj[0][0], mLightTransformOperation, ImGuizmo::WORLD, &mLightTransform[0][0], NULL, NULL);
}

void LocalScene::PointLightGui()
{
	ImGui::ColorEdit3("Color", &mLightColor.x);
	ImGui::InputFloat("Intensity", &mLightIntensity);
	ImGui::SliderFloat("Radius", &mLightRadius, 0.0f, 10.0f);

	mLightTransformOperation = ImGuizmo::TRANSLATE;

	glm::vec3 position;
	glm::vec3 rotation;
	glm::vec3 scale;

	ImGuizmo::BeginFrame();
	ImGuizmo::SetOrthographic(false);

	ImGuizmo::DecomposeMatrixToComponents(&mLightTransform[0][0], &position.x, &rotation.x, &scale.x);

	ImGui::InputFloat3("Position", &position.x);

	ImGuizmo::RecomposeMatrixFromComponents(&position.x, &rotation.x, &scale.x, &mLightTransform[0][0]);

	ImGuizmo::SetRect(0, 0, GRenderState->GetWidth(), GRenderState->GetHeight());
	ImGuizmo::Manipulate(&mCamera.mZmoView[0][0], &mCamera.mProj[0][0], mLightTransformOperation, ImGuizmo::WORLD, &mLightTransform[0][0], NULL, NULL);
}

void LocalScene::SpotLightGui()
{
	ImGui::ColorEdit3("Color", &mLightColor.x);
	ImGui::InputFloat("Intensity", &mLightIntensity);
	ImGui::SliderFloat("Radius", &mLightRadius, 0.0f, 10.0f);
	ImGui::SliderFloat("Inner Cone Angle", &mLightConeAngleInner, 1.0f, 100.0f);
	ImGui::SliderFloat("Outer Cone Angle", &mLightConeAngleOuter, 1.0f, 100.0f);

	if (ImGui::RadioButton("Translate", mLightTransformOperation == ImGuizmo::TRANSLATE))
		mLightTransformOperation = ImGuizmo::TRANSLATE;

	ImGui::SameLine();

	if (ImGui::RadioButton("Rotate", mLightTransformOperation == ImGuizmo::ROTATE))
		mLightTransformOperation = ImGuizmo::ROTATE;

	glm::vec3 position;
	glm::vec3 rotation;
	glm::vec3 scale;

	ImGuizmo::BeginFrame();
	ImGuizmo::SetOrthographic(false);

	ImGuizmo::DecomposeMatrixToComponents(&mLightTransform[0][0], &position.x, &rotation.x, &scale.x);

	ImGui::InputFloat3("Position", &position.x);
	ImGui::InputFloat3("Rotation", &rotation.x);

	ImGuizmo::RecomposeMatrixFromComponents(&position.x, &rotation.x, &scale.x, &mLightTransform[0][0]);

	ImGuizmo::SetRect(0, 0, GRenderState->GetWidth(), GRenderState->GetHeight());
	ImGuizmo::Manipulate(&mCamera.mZmoView[0][0], &mCamera.mProj[0][0], mLightTransformOperation, ImGuizmo::WORLD, &mLightTransform[0][0], NULL, NULL);
}

void LocalScene::OnExit()
{

}